/**
 * 可以从属性文件读取错误信息的例外
 */
package com.cnfangmao.exception;

import org.apache.log4j.Logger;
import org.springframework.util.StringUtils;

import com.cnfangmao.util.Asserter;
import com.cnfangmao.util.PropertiesUtil;
import com.cnfangmao.util.PropertiesUtil.PropertiesDelegator;


public class PropertyException extends RuntimeException {
	private static final long serialVersionUID = 1L;

	private static final String APPLICATION_PROPERTIES_FILE="application";
	private static final String EXCEPTION_PROPERTIES_FILE="exception.message.file";
	private static final String EXCEPTION_PROPERTIES_LOCAL="exception.message.locale";
	private static final String EXCEPTION_MESSAGE_ID="_ID";
	private static final String EXCEPTION_MESSAGE_PROCESSOR="_P";
	
//	private static final String EXCEPTION_PROPERTIES_ENCODE="UTF-8";

	private static Logger logger = Logger.getLogger(PropertyException.class); 
	
	private int ErrorID=0;  //例外ID号
	private Object objHandler=null;  //例外处理对象
	
	public int getErrorID() {
		return ErrorID;
	}
	public void setErrorID(int errorID) {
		ErrorID = errorID;
	}
	public Object getObjHandler() {
		return objHandler;
	}
	public void setObjHandler(Object objHandler) {
		this.objHandler = objHandler;
	}

	/***
	 * 从例外消息属性文件中读取strMsgPrefix对应的例外消息
	 * @param strMsgPrefix
	 * @return
	 */
	private static String getExceptionMsg(String strMsgPrefix,String moduleName,Object ...args)
	{
		String strMsg=null;
		String strPackageName=StringUtils.isEmpty(moduleName)?APPLICATION_PROPERTIES_FILE:moduleName;
		
		try
		{
			Asserter.hasLength(strMsgPrefix, "传入例外消息前缀为空");
			Asserter.hasLength(strPackageName, "获取例外消息属性文件包名出错");
			
			PropertiesDelegator delegator=PropertiesUtil.readPropertiesFile4ClassPath(APPLICATION_PROPERTIES_FILE);
			if(delegator!=null)
			{
				String strExceptionMsgProperties=(String)delegator.getProperty(EXCEPTION_PROPERTIES_FILE);
				String strExceptionMsgLocal=(String)delegator.getProperty(EXCEPTION_PROPERTIES_LOCAL);
				Asserter.hasLength(strExceptionMsgProperties, "没有设置例外消息属性文件");
				Asserter.hasLength(strExceptionMsgLocal, "没有设置例外消息区域信息");
				
				strExceptionMsgProperties=strPackageName+"."+strExceptionMsgProperties+"_"+strExceptionMsgLocal;
				
				delegator=PropertiesUtil.readPropertiesFile4ClassPath(strExceptionMsgProperties);
				strMsg=(String)delegator.getProperty(strMsgPrefix);
				if(StringUtils.isEmpty(strMsg))
				{
					delegator=PropertiesUtil.readPropertiesFile4ClassPath(APPLICATION_PROPERTIES_FILE);
					strMsg=(String)delegator.getProperty(strMsgPrefix);
				}
				Asserter.hasLength(strMsg,"例外["+strMsgPrefix+"]找不到对应的例外消息");

				strMsg=String.format(strMsg, args);
			
			}
		}
		catch(Exception e)
		{
			logger.error(e.getMessage(),e);
		}
		return strMsg;
	}

	/****
	 * 设置例外ID与处理器
	 * @param strMsgPrefix
	 */
	private void setExceptionIDandProcessor(String strMsgPrefix,String moduleName)
	{
		String strPackageName=StringUtils.isEmpty(moduleName)?APPLICATION_PROPERTIES_FILE:moduleName;

		try
		{

			PropertiesDelegator delegator=PropertiesUtil.readPropertiesFile4ClassPath(APPLICATION_PROPERTIES_FILE);
			if(delegator!=null)
			{
				String strExceptionMsgProperties=(String)delegator.getProperty(EXCEPTION_PROPERTIES_FILE);
				String strExceptionMsgLocal=(String)delegator.getProperty(EXCEPTION_PROPERTIES_LOCAL);
				Asserter.hasLength(strExceptionMsgProperties, "没有设置例外消息属性文件");
				Asserter.hasLength(strExceptionMsgLocal, "没有设置例外消息区域信息");
				
				strExceptionMsgProperties=strPackageName+"."+strExceptionMsgProperties+"_"+strExceptionMsgLocal;
				
				delegator=PropertiesUtil.readPropertiesFile4ClassPath(strExceptionMsgProperties);
				
				String strMsgID=(String)delegator.getProperty(strMsgPrefix+EXCEPTION_MESSAGE_ID);
				String strMsgProcessor=(String)delegator.getProperty(strMsgPrefix+EXCEPTION_MESSAGE_PROCESSOR);
				
				if(StringUtils.isEmpty(strMsgID))
				{
					delegator=PropertiesUtil.readPropertiesFile4ClassPath(APPLICATION_PROPERTIES_FILE);
					strMsgID=(String)delegator.getProperty(strMsgPrefix+EXCEPTION_MESSAGE_ID);
					strMsgProcessor=(String)delegator.getProperty(strMsgPrefix+EXCEPTION_MESSAGE_PROCESSOR);
				}
				
				Asserter.hasLength(strMsgID,"例外["+strMsgPrefix+"]找不到对应的例外ID");
				Asserter.isNumber(strMsgID, "例外["+strMsgPrefix+"]的例外ID不为数字");
	//			Asserter.hasLength(strMsgProcessor,"例外["+strMsgPrefix+"]找不到对应的例外处理消息");
				
				ErrorID=Integer.parseInt(strMsgID);
				objHandler=strMsgProcessor;
			}
		}
		catch(Exception e)
		{
			logger.error(e.getMessage(),e);
		}
	}
	
	public PropertyException(String strMsgPrefix,String moduleName, Object ...args)
	{
		super(getExceptionMsg(strMsgPrefix,moduleName,args));
		setExceptionIDandProcessor(strMsgPrefix,moduleName);
	}
	
}
